<?php

namespace app\common\service;

use app\api\model\UserCoupon as UserCouponModel;
use app\common\enum\order\PayStatus;
use app\common\enum\order\PayType;
use app\common\library\helper;
use app\common\model\video\CourseCate;
use app\common\model\video\CourseOrder;
use app\common\model\video\OrderPart;
use app\common\model\video\UserCourse;
use think\Db;
use think\exception\ValidateException;
use think\Validate;
use app\common\model\video\Course as CourseModel;
use app\common\validate\CoursePart;
use app\common\model\video\CoursePart as PartModel;

/**课程服务类
 * Class Course
 * @package app\common\service
 */
class Course
{
    public function __construct()
    {
        $this->model = new CourseModel();
    }

    //课程列表
    public function lists($where = [], $with = [])
    {
        $list = $this->model->getList($where, $with);
//        foreach ($list as &$item) {
//            $item['cover_image'] = img($item['cover_image']);
//        }

        return $list;
    }

    //课程分类
    public function cates()
    {
        $list = (new CourseCate())->order(['sort' => 'asc'])->field('id,name,sort')->select();
        return $list;
    }

    /**
     * 添加分类
     * @param array $params
     * @return bool
     */
    public function addCate(array $params = []): bool
    {
        if (empty($params['name']) || $params['name'] == '') {
            throw new ValidateException('请输入分类名称');
        }
        $insert['name'] = $params['name'];
        $insert['sort'] = isset($params['sort']) ?$params['sort'] : 0;
        return (new CourseCate())->add($insert) != false;
    }

    /**
     * 分类编辑
     * @param int $id
     * @param array $params
     * @return bool
     */
    public function editCate(int $id, array $params): bool
    {
        $detail = CourseCate::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('编辑失败1');
        }
        if (empty($params['name']) || $params['name'] == '') {
            throw new ValidateException('请输入分类名称');
        }
        $insert['name'] = $params['name'];
        $insert['sort'] = isset($params['sort']) ?$params['sort']: 0;
        return $detail->save($insert) !== false;
    }

    /**
     * 删除分类
     * @param int $id
     * @return bool
     */
    public function delCate(int $id): bool
    {
        $detail = CourseCate::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('分类不存在');
        }
        // 是否分类已使用
        $count = $this->model->where(['cate_id' => $id])->count();
        if ($count) {
            throw new ValidateException('当前分类已被使用');
        }
        return $detail->delete();
    }

    /**
     * 添加课程
     * @param array $params
     * @return int|string
     */
    public function addCourse(array $params = [])
    {
        $validate = new \app\common\validate\Course();
        if (!$validate->check($params)) {
            throw new ValidateException($validate->getError());
        }
        if ($params['validate_type'] == 2){
            if ($params['days'] == ''){
                throw new ValidateException('请选择有效期');
            }
            if (strtotime($params['days']) <= time()){
                throw new ValidateException('有效期必须在今天之后');
            }
        }else{
            $params['days'] = '';
        }
        $params['create_time'] = time();
        return $this->model->add($params);
    }

    /**
     * 编辑课程
     * @param int $id
     * @param array $params
     * @return bool
     */
    public function editCourse(int $id, array $params): bool
    {
        $detail = CourseModel::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('课程不存在');
        }
        $validate = new \app\common\validate\Course();
        if (!$validate->check($params)) {
            throw new ValidateException($validate->getError());
        }
        if ($params['validate_type'] == 2){
            if ($params['days'] == ''){
                throw new ValidateException('请选择有效期');
            }
            if (strtotime($params['days']) <= time()){
                throw new ValidateException('有效期必须在今天之后');
            }
        }else{
            $params['days'] = '';
        }
        return $detail->save($params) !== false;
    }

    /**
     * 删除课程
     * @param int $id
     * @return bool
     */
    public function delCourse(int $id): bool
    {
        $detail = CourseModel::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('课程不存在');
        }
        // 章节内容
        $count = (new PartModel())->where(['c_id' => $id])->count();
        if ($count) {
            throw new ValidateException('当前课程含有章节内容');
        }
        // 是否被购买
        $count = (new UserCourse())->where(['c_id' => $id])->count();
        if ($count) {
            throw new ValidateException('当前课程已被购买');
        }
        return $detail->delete();
    }

    public function stateCourse($data){
        $detail = CourseModel::get(['id' => $data['id']]);
        if (empty($detail)) {
            throw new ValidateException('课程不存在');
        }
        return $detail->allowField(true)->save(['status' => $data['state'] ? 1 : 2]) !== false;
    }

    /**
     * @param int $c_id
     * @return mixed
     */
    public function listPart(array $where = [])
    {
        $params = array_merge([
            'name'=>'',
            'c_id'=>''
        ],$where);
        $filter = [];
        $params['name'] != '' && $filter['name'] = ['like','%'.$params['name'].'%'];
        $params['c_id'] != '' && $filter['c_id'] = $params['c_id'];
        return (new PartModel())->with(['video','course','image'])
            ->where($filter)->order(['id' => 'desc'])->paginate();
    }

    /**
     * 添加章节
     * @param array $params
     * @return bool
     */
    public function addPart(array $params): bool
    {
        $validate = new CoursePart();
        if (!$validate->check($params)) {
            throw new ValidateException($validate->getError());
        }
        return (new PartModel())->add($params) !== false;
    }

    /**
     * 编辑章节
     * @param int $id
     * @param array $params
     * @return bool
     */
    public function editPart(int $id, array $params): bool
    {
        $detail = PartModel::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('编辑失败1');
        }
        $validate = new CoursePart();
        if (!$validate->scene('edit')->check($params)) {
            throw new ValidateException($validate->getError());
        }
        return $detail->save($params) !== false;
    }

    /**
     * 删除章节
     * @param int $id
     * @return bool
     */
    public function delPart(int $id): bool
    {
        $detail = PartModel::get(['id' => $id]);
        if (empty($detail)) {
            throw new ValidateException('没有此章节');
        }
        // 是否被购买
        $count = (new UserCourse())->where(['c_id' => $detail['c_id']])->count();
        if ($count > 0) {
            throw new ValidateException('当前课程已被购买');
        }
        return $detail->delete();
    }


    //课程详情
    public function detail($id, $uid = 0)
    {
        $data = $this->model->where('id', $id)->with(['part.video'])->find();
        if(!$data){
            throw new ValidateException('课程不存在');
        }
        $is_buy = false;
        if ($uid && (new UserCourse())->where('user_id', $uid)
                ->where('c_id', $id)->find()) {
            $is_buy = true;
        }
        $data['is_buy'] = $is_buy;
        $data['cover_image'] = img($data['cover_image']);
        $data['sales'] = (new CourseOrder())->where('c_id', $id)->where('pay_status', 20)->count();
        if(isset($data['part'])){
            foreach ($data['part'] as &$item){
                $item['url'] = isset($item['video']) &&  $item['video'] ? $item['video']['external_url']:'';
            }
        }

        return $data;
    }


    //购买课程
    public function createOrder($id, $uid,$coupon_id = 0)
    {
        //在有效期内的课程
        if ((new UserCourse())->where('user_id', $uid)->where('status',1)
            ->where('c_id', $id)->find()) {
            throw new ValidateException('此课程已购买');
        }

        $course = $this->model->where('is_delete', 0)
            ->where('status', 1)->where('id', $id)->find();
        if (!$course) {
            throw new ValidateException('课程不存在或已下架');
        }
        $pay_money = $course['price'];
        $coupon_money = 0;
        if($coupon_id > 0){
            //可用优惠券
            $couponList = UserCouponModel::getUserCouponList($uid,$pay_money);
            // 获取优惠券信息
            $couponInfo = helper::getArrayItemByColumn($couponList, 'user_coupon_id', $coupon_id);
            if ($couponInfo == false) {
                throw new ValidateException('未找到优惠券信息');
            }
            $pay_money = $pay_money - $couponInfo['reduced_price'];
            $coupon_money = $couponInfo['reduced_price'];
        }
        $order = new CourseOrder();
        $order->save([
            'user_id' => $uid,
            'c_id' => $id,
            'out_trade_no' => 'C' . Order::createOrderNo(),
            'total_price' => max(0, $course['price']),
            'pay_price' => max(0, $pay_money),
            'body' => '购买课程' . $course['name'],
            'wxapp_id'=>$course['wxapp_id'],
            'validate_type'=>$course['validate_type'],//长期还是自定义
            'end_time'=>$course['days'],  //结束时间
            'coupon_id'=>$coupon_id,//优惠券
            'coupon_money'=>$coupon_money //优惠金额
        ]);
        return $order;
    }

    //支付成功回调业务
    public function paySuccess(array $orderinfo = [], $pay_type = PayType::BALANCE, $other = [])
    {
        $model = CourseOrder::get(['order_id' => $orderinfo['order_id']]);
        Db::startTrans();
        try {
            $save['pay_type'] = $pay_type;
            $save['pay_status'] = PayStatus::SUCCESS;
            $save['pay_time'] = time();
            if ($pay_type == PayType::WECHAT) {
                if (isset($other['transaction_id'])) {
                    $save['transaction_id'] = $other['transaction_id'];
                }
            }
            $model->save($save);

            $user_course = new UserCourse();
            $user_course->save([
                'user_id' => $model['user_id'],
                'order_id' => $model['order_id'],
                'c_id' => $model['c_id'],
                'validate_type' => $model['validate_type'],
                'end_time' => $model['end_time'],
                'wxapp_id'=>$model['wxapp_id']
            ]);
            //用户课程的章节
            $CoursePart = new \app\common\model\video\CoursePart();
            $part = $CoursePart->getCoursePart($model['c_id']);
            $data = array_map(function ($item) use ($user_course,$model){
                return [
                    'user_course_id'=>$user_course['id'],
                    'c_id'=>$model['c_id'],
                    'part_id'=>$item['id'],
                    'wxapp_id'=>$model['wxapp_id']
                ];
            },$part->toArray());

            $orderPartModel = new OrderPart();
            $orderPartModel->saveAll($data);

            Db::commit();
            return true;
        } catch (\Throwable $e) {
            Db::rollback();
            return false;
        }
    }

    public function getOrderInfo($order_id)
    {
        return CourseOrder::get(['order_id' => $order_id]);
    }

    /**
     * @title 待付款的视频订单
     * @param $orderNo
     * @author Qian
     * Time: 2023/4/7  10:31
     */
    public function getOrderDetail($orderNo)
    {
        return CourseOrder::get(['out_trade_no' => $orderNo,'pay_status'=>10]);
    }
}
